<?php

namespace App\Http\Controllers\AgentAdmin;

use App\Exports\FrontendExport;
use App\Exports\UserAssetExport;
use App\Exports\UserLoginHistoryExport;
use App\Http\Controllers\Controller;
use App\Jobs\DownloadsJob;
use App\Models\AgentUser;
use App\Models\Channel;
use App\Models\Download;
use App\Models\FrontendUser;
use App\Models\LoginHistory;
use App\Models\Punish;
use Carbon\Carbon;
use Vinlon\Laravel\LayAdmin\Exceptions\AdminException;
use Vinlon\Laravel\LayAdmin\PaginateResponse;

class UserController extends Controller
{
    public function listUsers()
    {
        /** @var AgentUser $user */
        $user = auth()->user();
        $query = $this->getUserQuery($user->agent_id)
            ->with(['auth', 'channel', 'parent', 'punish_log'])
            ->orderByDesc('id');

        return paginate_result($query);
    }

    public function updateSource($userId)
    {
        request()->validate([
            'invitor_mobile' => 'nullable',
            'channel_code' => 'nullable',
        ]);
        $invitorMobile = request()->invitor_mobile;
        $channelCode = request()->channel_code;
        /** @var AgentUser $agentUser */
        $agentUser = auth()->user();
        /** @var FrontendUser $user */
        $user = FrontendUser::query()->find($userId);
        if ($invitorMobile) {
            /** @var FrontendUser $parent */
            $parent = FrontendUser::query()->where('agent_id', $agentUser->agent_id)
                ->where('mobile', $invitorMobile)->first();
            if (!$parent) {
                throw new AdminException('邀请人手机号不存在');
            }
            if ($parent->created_at->lte($user)) {
                throw new AdminException('邀请人注册时间晚于当前用户');
            }
            $user->parent_id = $parent->id;
        } else {
            $user->parent_id = 0;
        }
        if ($channelCode) {
            /** @var Channel $channel */
            $channel = Channel::query()->where('agent_id', $agentUser->agent_id)->where('uuid', $channelCode)->first();
            if (!$channel) {
                throw new AdminException('无效的渠道码');
            }
            $user->channel_id = $channel->id;
            $user->save();
        } else {
            $user->channel_id = 0;
        }
        $user->save();
    }

    public function export()
    {
        /** @var AgentUser $user */
        $user = auth()->user();
        $file = '用户导出' . date('YmdHis') . uniqid() . '.xls';

        $count = $this->getUserQuery($user->agent_id)->count();
        if ($count > 50000) {
            throw new AdminException('导出用户数量大于5万条，请增加筛选条件分批导出');
        }
        if (0 == $count) {
            throw new AdminException('未查到用户记录');
        }
        $download = Download::create([
            'agent_id' => $user->agent_id,
            'user_id' => $user->id,
            'name' => $file,
            'url' => 'storage/' . $file,
            'status' => 0,
            'model' => FrontendExport::class,
            'request' => json_encode(request()->all()),
        ]);

        dispatch(new DownloadsJob($download));
    }

    public function punish_config()
    {
        FrontendUser::where('id', request()->id)->update(['punish' => 1]);

        $save = [
            'user_id' => request()->id,
            'punish_day' => request()->punish_day,
            'punish_type' => request()->type ?? 1,
            'punish_status' => 1,
            'end_time' => Carbon::now()->addDays(request()->punish_day),
        ];

        Punish::create($save);
    }

    public function unpunish_config()
    {
        FrontendUser::where('id', request()->id)->update(['punish' => 0]);

        Punish::where('user_id', request()->id)->where('punish_status', 1)
            ->update(['punish_status' => 2]);
    }

    /** 导出用户持有资产 */
    public function exportAssets($userId)
    {
        /** @var FrontendUser $user */
        $frontendUser = FrontendUser::query()->find($userId);

        /** @var AgentUser $user */
        $user = auth()->user();

        $fileName = sprintf('[%s]资产导出_%s.xlsx', $frontendUser->mobile, now()->format('YmdHis'));
        $download = Download::create([
            'agent_id' => $user->agent_id,
            'user_id' => $user->id,
            'name' => $fileName,
            'url' => '',
            'status' => 0,
            'model' => UserAssetExport::class,
            'request' => json_encode(['user_id' => $userId]),
        ]);

        DownloadsJob::dispatch($download);
    }

    public function loginHistory(): PaginateResponse
    {
        /** @var AgentUser $user */
        $user = auth()->user();

        $query = LoginHistory::query()
            ->select(['login_histories.created_at', 'login_histories.channel_id', 'login_histories.login_mode', 'frontend_users.mobile'])
            ->leftJoin('frontend_users', 'frontend_users.id', 'login_histories.user_id')
            ->where('agent_id', $user->agent_id)
            ->with(['channel'])
            ->when(request()->keyword, function ($q) {
                $likeVal = '%' . request()->keyword . '%';

                return $q->where('mobile', 'like', $likeVal);
            })
            ->when(request()->channel_id, function ($q) {
                return $q->where('login_histories.channel_id', request()->channel_id);
            })
            ->when(request()->login_mode, function ($q) {
                return $q->where('login_histories.login_mode', request()->login_mode);
            })
            ->when(request()->start_date, function ($q) {
                return $q->where('login_histories.created_at', '>=', Carbon::parse(request()->start_date)->startOfDay());
            })
            ->when(request()->end_date, function ($q) {
                return $q->where('login_histories.created_at', '<=', Carbon::parse(request()->end_date)->endOfDay());
            })
            ->orderByDesc('login_histories.id');

        return paginate_result($query);
    }

    public function loginHistoryExport()
    {
        /** @var AgentUser $user */
        $user = auth()->user();

        $file = '登录历史' . date('YmdHis') . uniqid() . '.xls';

        $download = Download::create([
            'agent_id' => $user->agent_id,
            'user_id' => $user->id,
            'name' => $file,
            'url' => 'storage/' . $file,
            'status' => 0,
            'model' => UserLoginHistoryExport::class,
            'request' => json_encode(request()->all()),
        ]);

        dispatch(new DownloadsJob($download));
    }

    private function getUserQuery($agentId)
    {
        return FrontendUser::query()
            ->when(request()->keyword, function ($q) {
                $likeVal = '%' . request()->keyword . '%';

                return $q->where('nickname', 'like', $likeVal)->orWhere('mobile', 'like', $likeVal);
            })
            ->when(request()->start_date, function ($q) {
                $startTime = Carbon::parse(request()->start_date)->startOfDay();

                return $q->where('created_at', '>=', $startTime);
            })
            ->when(request()->end_date, function ($q) {
                $endTime = Carbon::parse(request()->end_date)->endOfDay();

                return $q->where('created_at', '<=', $endTime);
            })
            ->where('agent_id', $agentId);
    }
}
